const canvas = document.getElementById('game-canvas');
const ctx = canvas.getContext('2d');

// 添加双缓冲
const bufferCanvas = document.createElement('canvas');
const bufferCtx = bufferCanvas.getContext('2d');
bufferCanvas.width = canvas.width;
bufferCanvas.height = canvas.height;

const cellSize = 40;
const gridWidth = canvas.width / cellSize;
const gridHeight = canvas.height / cellSize;
let eatenDots = 0; // 吃掉的豆子数量
const pacman = {
    x: null,
    y: null,
    direction: 'right',
    speed: 0,
    mouthAngle: 0,
    mouthOpenSpeed: 0.15,
    mouthMaxAngle: Math.PI / 4,
    mouthState: 'closing',
    lastUpdate: 0,
    updateInterval: 16,
    invincible: false, // 新增无敌状态
    invincibleEnd: 0 // 无敌状态结束时间
};

// 新增生命值和计时器
let lives = 4; // 生命值
let timer = 120; // 计时器，单位为秒
let startTime = null; // 游戏开始时间

// 初始化障碍物和豆子
const wallProbability = 0.05;
let walls = [];
let dots = [];

// 添加一个新函数来检查位置是否在墙的周围
function isNextToWall(x, y) {
    for (let i = -1; i <= 1; i++) {
        for (let j = -1; j <= 1; j++) {
            const checkX = x + i;
            const checkY = y + j;
            if (isWall(checkX, checkY)) {
                return true;
            }
        }
    }
    return false;
}

function initializeGame() {
    walls = [];
    dots = [];
    lives = 4; // 重置生命值
    collisionCount = 0; // 重置碰撞计数器
    timer = 120; // 重置倒计时为120秒
    pacman.invincible = false; // 重置无敌状态
    pacman.invincibleEnd = 0; // 重置无敌状态结束时间

    // 随机生成障碍物
    for (let i = 0; i < gridWidth; i++) {
        for (let j = 0; j < gridHeight; j++) {
            if (Math.random() < wallProbability) {
                walls.push({ x: i, y: j });
            }
        }
    }

    // 初始化豆子，确保不在墙的周围
    for (let i = 0; i < gridWidth; i++) {
        for (let j = 0; j < gridHeight; j++) {
            if (!isWall(i, j) && !isNextToWall(i, j)) {
                dots.push({ x: i, y: j });
            }
        }
    }

    // 确保至少有一些豆子
    if (dots.length === 0) {
        console.warn("No dots placed, adjusting wall placement");
        walls = walls.slice(0, Math.floor(walls.length / 2));
        return initializeGame(); // 重新初始化游戏
    }

    setPacmanStartPosition();
    startTime = Date.now(); // 重新记录游戏开始时间
    updateUI(); // 更新 UI

    // 初始化生命值图案
    const livesContainer = document.getElementById('lives-container');
    livesContainer.innerHTML = '<span id="lives">Lives: </span>'; // 清空旧图案
    for (let i = 0; i < lives; i++) {
        const heartIcon = document.createElement('span');
        heartIcon.classList.add('heart-icon');
        heartIcon.textContent = '❤️'; // 使用小红心符号
        heartIcon.style.marginRight = '5px'; // 添加一些间距
        livesContainer.appendChild(heartIcon);
    }

    // 确保动画循环重新启动
    requestAnimationFrame(update);
}

function isWall(x, y) {
    return walls.some(wall => wall.x === x && wall.y === y);
}

function setPacmanStartPosition() {
    // 创建可用位置的列表（不是墙的位置）
    let availablePositions = [];

    // 收集所有没有墙的位置
    for (let x = 0; x < gridWidth; x++) {
        for (let y = 0; y < gridHeight; y++) {
            if (!isWall(x, y)) {
                availablePositions.push({ x, y });
            }
        }
    }

    // 如果没有可用位置，清除一些墙
    if (availablePositions.length === 0) {
        console.warn("No available positions found, clearing some walls");
        walls = walls.slice(0, Math.floor(walls.length / 2));
        return setPacmanStartPosition(); // 递归调用
    }

    // 从可用位置中随机选择一个
    const randomIndex = Math.floor(Math.random() * availablePositions.length);
    const startPosition = availablePositions[randomIndex];

    // 设置 Pacman 的位置，增加 0.5 使 Pacman 位于格子中央
    pacman.x = startPosition.x + 0.5;
    pacman.y = startPosition.y + 0.5;
}

function isColliding(x, y) {
    const gridX = Math.floor(x);
    const gridY = Math.floor(y);

    for (let i = -1; i <= 1; i++) {
        for (let j = -1; j <= 1; j++) {
            const checkX = gridX + i;
            const checkY = gridY + j;
            if (isWall(checkX, checkY)) {
                const wallCenterX = checkX + 0.5;
                const wallCenterY = checkY + 0.5;
                const distance = Math.sqrt(
                    Math.pow(x - wallCenterX, 2) +
                    Math.pow(y - wallCenterY, 2)
                );
                if (distance < 0.8) {
                    return true;
                }
            }
        }
    }
    return false;
}

function directionToAngle(direction) {
    switch (direction) {
        case 'right':
            return 0;
        case 'left':
            return Math.PI;
        case 'up':
            return -Math.PI / 2;
        case 'down':
            return Math.PI / 2;
        default:
            return 0;
    }
}

function update(currentTime) {
    if (currentTime - pacman.lastUpdate < pacman.updateInterval) {
        requestAnimationFrame(update);
        return;
    }
    pacman.lastUpdate = currentTime;

    bufferCtx.fillStyle = 'black';
    bufferCtx.fillRect(0, 0, canvas.width, canvas.height);

    if (pacman.mouthState === 'closing') {
        pacman.mouthAngle -= pacman.mouthOpenSpeed;
        if (pacman.mouthAngle <= 0) {
            pacman.mouthAngle = 0;
            pacman.mouthState = 'opening';
        }
    } else if (pacman.mouthState === 'opening') {
        pacman.mouthAngle += pacman.mouthOpenSpeed;
        if (pacman.mouthAngle >= pacman.mouthMaxAngle) {
            pacman.mouthAngle = pacman.mouthMaxAngle;
            pacman.mouthState = 'closing';
        }
    }

    let newX = pacman.x;
    let newY = pacman.y;

    switch (pacman.direction) {
        case 'right':
            newX += pacman.speed;
            break;
        case 'left':
            newX -= pacman.speed;
            break;
        case 'up':
            newY -= pacman.speed;
            break;
        case 'down':
            newY += pacman.speed;
            break;
    }

    if (!isColliding(newX, newY)) {
        pacman.x = newX;
        pacman.y = newY;
    } else if (!pacman.invincible) { // 如果不是无敌状态，扣除生命值
        lives--;
        if (lives === 0) {
            // 当生命值为0时，弹出提示框并等待用户点击“确定”
            const resetGame = confirm('游戏结束，生命值归0，点击“确定”重新开始！');
            if (resetGame) {
                initializeGame(); // 重置游戏
            } else {
            // 如果用户点击取消，则停止游戏
                return;
            }
        } else {
            pacman.invincible = true; // 进入无敌状态
            pacman.invincibleEnd = Date.now() + 2000; // 无敌状态持续2秒

        // 更新生命值图案
            const heartIcons = document.querySelectorAll('.heart-icon');
            if (heartIcons.length > lives) {
                heartIcons[lives].style.display = 'none'; // 隐藏一个生命值图案
            }
        }
    }
    pacman.x = Math.max(0.5, Math.min(gridWidth - 0.5, pacman.x));
    pacman.y = Math.max(0.5, Math.min(gridHeight - 0.5, pacman.y));

    // 检查是否吃到豆子（使用新的检测函数）
    checkAndEatDots();

    drawWalls(bufferCtx, walls, cellSize, 2); // 2是边框宽度
    drawDots(bufferCtx);
    drawPacman(bufferCtx);

    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(bufferCanvas, 0, 0);

    // 检查游戏是否胜利
    if (dots.length === 0) {
        alert('恭喜你赢了！');
        initializeGame(); // 重置游戏
        return;
    }

    // 检查计时器是否超时
    if (Date.now() - startTime > timer * 1000) {
        alert('时间到，游戏结束');
        initializeGame(); // 重置游戏
        return;
    }

    // 检查无敌状态是否结束
    if (pacman.invincible && Date.now() >= pacman.invincibleEnd) {
        pacman.invincible = false; // 结束无敌状态
    }
    // 每次更新游戏状态时调用 updateUI 更新倒计时
    updateUI();
    requestAnimationFrame(update);
}

// 新增吃豆子检测函数
function checkAndEatDots() {
    const eatRadius = 0.6; // 减小吃豆半径使判定更严格
    const pacmanCenterX = pacman.x;
    const pacmanCenterY = pacman.y;

    dots = dots.filter(dot => {
        const dotCenterX = dot.x + 0.5;
        const dotCenterY = dot.y + 0.5;

        const distance = Math.sqrt(
            Math.pow(dotCenterX - pacmanCenterX, 2) +
            Math.pow(dotCenterY - pacmanCenterY, 2)
        );

        // 添加额外的方向检查
        let inRange = distance <= eatRadius;

        // 根据吃豆人的朝向增加额外的判定
        if (inRange) {
            switch (pacman.direction) {
                case 'right':
                    inRange = dotCenterX >= pacmanCenterX;
                    break;
                case 'left':
                    inRange = dotCenterX <= pacmanCenterX;
                    break;
                case 'up':
                    inRange = dotCenterY <= pacmanCenterY;
                    break;
                case 'down':
                    inRange = dotCenterY >= pacmanCenterY;
                    break;
            }
        }

        if (!inRange) {
            return true; // 保留豆子
        } else {
            eatenDots++; // 吃掉豆子，增加计数
            return false; // 移除豆子
            }
    });
}

function drawPacman(context) {
    const { x, y, mouthAngle } = pacman;
    const pacmanSize = cellSize;
    const centerX = x * cellSize;
    const centerY = y * cellSize;

    context.save();
    context.translate(centerX, centerY);
    context.rotate(directionToAngle(pacman.direction));

    // 绘制身体（黄色圆形）
    context.fillStyle = 'yellow';
    context.beginPath();
    context.arc(0, 0, pacmanSize / 2, mouthAngle, Math.PI * 2 - mouthAngle);
    context.lineTo(0, 0);
    context.closePath();
    context.fill();

    // 绘制眼睛
    context.fillStyle = 'black';
    context.beginPath();
    let eyeYOffset = -pacmanSize / 4; // 默认眼睛在嘴巴上方
    if (pacman.direction === 'left') {
        eyeYOffset = pacmanSize / 4; // 向左移动时眼睛在嘴巴下方
    }
    const eyeX = pacman.direction === 'left' ? -pacmanSize / 6 : pacmanSize / 6;
    context.arc(eyeX, eyeYOffset, pacmanSize / 10, 0, Math.PI * 2);
    context.fill();

    context.restore();
}

function drawDots(context) {
    context.fillStyle = 'white';
    dots.forEach(dot => {
        context.beginPath();
        context.arc(
            dot.x * cellSize + cellSize / 2,
            dot.y * cellSize + cellSize / 2,
            cellSize / 6,
            0,
            Math.PI * 2
        );
        context.fill();
    });
}

function drawWalls(context, walls, cellSize, borderWidth = 2) {
    // 遍历墙壁数组并绘制每个墙壁
    walls.forEach(wall => {
        const startX = wall.x * cellSize;
        const startY = wall.y * cellSize;

        // 绘制红色背景
        context.fillStyle = 'red';
        context.fillRect(startX, startY, cellSize, cellSize);

        // 绘制白色边框
        context.strokeStyle = 'white';
        context.lineWidth = borderWidth;
        context.strokeRect(startX + borderWidth / 2, startY + borderWidth / 2,
                           cellSize - borderWidth, cellSize - borderWidth);
    });
}

// 新增UI更新函数
function updateUI() {
    const elapsedTime = Math.floor((Date.now() - startTime) / 1000); // 已过去的时间（秒）
    const remainingTime = Math.max(0, timer - elapsedTime); // 剩余时间
    document.getElementById('timer').textContent = `Time: ${remainingTime}s`;
    document.getElementById('eaten-dots').textContent = `Eaten Dots: ${eatenDots}`; // 更新吃掉的豆子数量
}

// 键盘控制
document.addEventListener('keydown', (e) => {
    switch (e.key) {
        case 'ArrowUp':
            pacman.direction = 'up';
            pacman.speed = 0.06; // 设置速度
            break;
        case 'ArrowDown':
            pacman.direction = 'down';
            pacman.speed = 0.06; // 设置速度
            break;
        case 'ArrowLeft':
            pacman.direction = 'left';
            pacman.speed = 0.06; // 设置速度
            break;
        case 'ArrowRight':
            pacman.direction = 'right';
            pacman.speed = 0.06; // 设置速度
            break;
    }
});

// 触摸控制
let touchStartX, touchStartY;

canvas.addEventListener('touchstart', (e) => {
    e.preventDefault();
    const touch = e.touches[0];
    touchStartX = touch.clientX;
    touchStartY = touch.clientY;
}, { passive: false });

canvas.addEventListener('touchmove', (e) => {
    e.preventDefault();
    const touch = e.touches[0];
    const deltaX = touch.clientX - touchStartX;
    const deltaY = touch.clientY - touchStartY;

    if (Math.abs(deltaX) > Math.abs(deltaY)) {
        pacman.direction = deltaX > 0 ? 'right' : 'left';
        pacman.speed = 0.06; // 设置速度
    } else {
        pacman.direction = deltaY > 0 ? 'down' : 'up';
        pacman.speed = 0.06; // 设置速度
    }
}, { passive: false });

// 初始化并开始游戏
initializeGame();
requestAnimationFrame(update);